#include <gflags/gflags.h>
#include <butil/logging.h>
#include <brpc/server.h>
#include <opencv2/opencv.hpp>
#include "service.pb.h"
#include <json2pb/json_to_pb.h>  // brpc支持json和protobuf间的双向转化
#include <json2pb/pb_to_json.h>
#include <butil/base64.h>
#include <string>

DEFINE_int32(port, 8000, "TCP Port of this server");

namespace example {

class HttpServiceImpl : public HttpService {
public:
    HttpServiceImpl() {}

    void Echo(google::protobuf::RpcController* cntl_base,
              const HttpRequest*,
              HttpResponse*,
              google::protobuf::Closure* done) {
        brpc::ClosureGuard done_guard(done);
        brpc::Controller* cntl = static_cast<brpc::Controller*>(cntl_base);

        // 检查Content-Type
        if (cntl->http_request().content_type() != "application/json") {
            cntl->http_response().set_status_code(400);
            cntl->response_attachment().append("Content-Type must be application/json");
            return;
        }

        // 解析JSON请求
        std::string request_json = cntl->request_attachment().to_string();
        ImageRequest req;
        json2pb::Json2PbOptions options;
        options.base64_to_bytes = false;

        std::string error;
        if (!json2pb::JsonToProtoMessage(request_json, &req, options, &error)) {
            cntl->http_response().set_status_code(400);
            cntl->response_attachment().append("Invalid JSON format: " + error);
            return;
        }

        // 检查必要的字段
        if (req.image_data().empty()) {
            cntl->http_response().set_status_code(400);
            cntl->response_attachment().append("Missing image_data");
            return;
        }

        // 解码Base64图片数据
        std::string image_data;
        if (!butil::Base64Decode(req.image_data(), &image_data)) {
            cntl->http_response().set_status_code(400);
            cntl->response_attachment().append("Invalid base64 data");
            return;
        }

        // 将图片数据转换为OpenCV格式
        std::vector<uchar> img_data(image_data.begin(), image_data.end());
        cv::Mat img = cv::imdecode(img_data, cv::IMREAD_UNCHANGED);

        if (img.empty()) {
            cntl->http_response().set_status_code(400);
            cntl->response_attachment().append("Invalid image data");
            return;
        }

        // 在图像上绘制多个矩形
        std::vector<cv::Rect> rects = {
            cv::Rect(img.cols / 4, img.rows / 4, img.cols / 2, img.rows / 2),
            cv::Rect(img.cols / 8, img.rows / 8, img.cols / 4, img.rows / 4),
            cv::Rect(img.cols / 2, img.rows / 2, img.cols / 3, img.rows / 3)
        };

        // 绘制所有矩形
        for (const auto& rect : rects) {
            cv::rectangle(img, rect, cv::Scalar(0, 0, 255), 2);
        }
        cv::imwrite(req.image_name(), img);

        // 构建成功响应
        ImageResponse resp;

        // 设置单个message
        Rect img_rect;
        img_rect.set_x(0);
        img_rect.set_y(0);
        img_rect.set_w(img.cols);
        img_rect.set_h(img.rows);
        *resp.mutable_img_rect() = img_rect;  // 设置消息类型的字段

        // 设置多个message
        for (const auto& rect : rects) {
            Rect* rect_resp = resp.add_rect();
            rect_resp->set_x(rect.x);
            rect_resp->set_y(rect.y);
            rect_resp->set_w(rect.width);
            rect_resp->set_h(rect.height);
        }

        // 设置其他响应字段
        resp.set_success(true);
        resp.set_message("Image processed successfully");

        // 将处理后的图像编码为PNG
        std::vector<uchar> buf;
        cv::imencode(".png", img, buf);
        std::string processed_image(buf.begin(), buf.end());

        // Base64编码处理后的图像
        std::string encoded_image;
        butil::Base64Encode(processed_image, &encoded_image);
        resp.set_image_data(encoded_image);

        // 将响应转换为JSON
        std::string response_json;
        json2pb::Pb2JsonOptions json_options;
        // 在proto3中，如果一个字段的值是默认值（对于整数类型来说是0），在转换为JSON时会被省略
        json_options.always_print_primitive_fields = true;  // 这个设置表示不省略为默认值的字段
        json2pb::ProtoMessageToJson(resp, &response_json, json_options);

        cntl->http_response().set_content_type("application/json");
        cntl->response_attachment().append(response_json);
    }
};
}  // namespace example

int main(int argc, char* argv[]) {
    GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);

    brpc::Server server;
    example::HttpServiceImpl http_svc;

    // 添加服务实例，同时支持 protobuf RPC 和 HTTP
    if (server.AddService(&http_svc, brpc::SERVER_DOESNT_OWN_SERVICE) != 0) {
        LOG(ERROR) << "Fail to add http_svc";
        return -1;
    }

    // 启动服务器
    if (server.Start(FLAGS_port, NULL) != 0) {
        LOG(ERROR) << "Fail to start HttpServer";
        return -1;
    }

    server.RunUntilAskedToQuit();
    return 0;
}
